import math


class Vector:

    def __init__(self, lst):
        self.__values = list(lst)  # 复制一份，而不是传引用

    # 返回似有成员变量
    def get_values(self):
        return self.__values

    # 返回向量的迭代器
    def __iter__(self):
        return self.__values.__iter__()

    # 使用索引[i]取出某个数值
    def __getitem__(self, index):
        return self.__values[index]

    # 返回向量长度
    def __len__(self):
        return len(self.__values)

    # 显示向量(系统调用)
    def __repr__(self):
        return f'Vector({self.__values})'

    # 显示向量(用户调用)
    def __str__(self):
        return "({})".format(", ".join(str(i) for i in self.__values))

    # 向量相加(重载加号)
    def __add__(self, other):
        # 保证向量维度相等
        assert len(self) == len(other), \
            '向量维度不等，不能进行加法运算'
        return Vector([a + b for a, b in zip(self, other)])

    # 向量相减(重载减号)
    def __sub__(self, other):
        # 保证向量维度相等
        assert len(self) == len(other), \
            '向量维度不等，不能进行减法运算'
        return Vector([a - b for a, b in zip(self, other)])

    # 向量数乘(重载*号)    向量 * k
    def __mul__(self, k):
        return Vector([k * e for e in self])

    # k * 向量
    def __rmul__(self, k):
        return self * k

    # 向量点乘
    def dot(self, other):
        # 保证向量维度相等
        assert len(self) == len(other), \
            '向量维度不等,不能进行点乘运算'
        return sum(a * b for a, b in zip(self, other))

    # 返回向量取正的结果
    def __pos__(self):
        return 1 * self

    # 返回向量取负的结果
    def __neg__(self):
        return -1 * self

    # 实现dim维零向量
    @classmethod
    def zero(cls,dim): #类方法，维度
        return cls([0] * dim)

    # 求一个向量的模
    def norm(self):
        return math.sqrt(sum(e**2 for e in self))

    # 规范化
    def normalize(self):
        return Vector(self.__values) / self.norm()

    # 重载数量除法操作
    def __truediv__(self, k):
        assert k != 0 , \
            '除数不能为0'
        return (1/k)*self


if __name__ == '__main__':
    u1 = Vector([1, 2, 3, 4, 5])
    u2 = Vector([1, 2, 3, 4, 5])
    print(u1 + u2)
    print(u1 - u2)
    print(u1 * 3)
    print(3 * u1)
    print(+u1)
    print(-u1)
    print(Vector.zero(5))
    print(u1.norm())
    print(u1.normalize().norm())
    # print(Vector.zero(5).normalize())
    print(u1.dot(u2))
